package org.groupg.practice;

import okio.BufferedSource;
import okio.Okio;
import okio.Source;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CsvReaderWithOkio {

    /**
     * 读取 CSV 文件并将其内容解析为 List<Map<String, String>>
     * 每个 Map 代表一行数据，键为列名，值为对应的单元格数据
     *
     * @param file 要读取的 CSV 文件
     * @return 包含解析后数据的列表
     * @throws IOException 如果文件读取失败或格式有误
     */
    public static List<Map<String, String>> readCsv(File file) throws IOException {
        // 存储解析后的数据
        List<Map<String, String>> result = new ArrayList<>();
        // 存储列头信息
        List<String> headers = new ArrayList<>();

        // 使用 try-with-resources 语句确保资源被正确关闭:cite[1]
        try (Source source = Okio.source(file);
             BufferedSource bufferedSource = Okio.buffer(source)) {

            String line;
            boolean isFirstLine = true;

            // 逐行读取 CSV 文件:cite[2]:cite[7]
            while ((line = bufferedSource.readUtf8Line()) != null) {
                // 跳过空行
                if (line.trim().isEmpty()) {
                    continue;
                }

                // 解析一行 CSV，处理简单的引号转义和逗号分隔
                // 注意：这是一个简单实现，复杂的 CSV（如含引号内逗号）可能需要更复杂的解析器（如开源库）
                List<String> fields = parseCsvLine(line);

                if (isFirstLine) {
                    // 第一行作为列头
                    headers.addAll(fields);
                    isFirstLine = false;
                } else {
                    // 数据行：将字段与列头对应起来，组成 Map
                    if (fields.size() != headers.size()) {
                        // 实际应用中可能需要更精细的错误处理（如日志记录或跳过该行）
                        throw new IOException("CSV 数据行字段数量与列头数量不匹配: " + line);
                    }
                    Map<String, String> rowMap = new HashMap<>();
                    for (int i = 0; i < headers.size(); i++) {
                        rowMap.put(headers.get(i), fields.get(i));
                    }
                    result.add(rowMap);
                }
            }
        } // 这里会自动调用 bufferedSource.close() 和 source.close()，确保资源释放:cite[1]

        return result;
    }

    /**
     * 解析单行 CSV 字符串，分割字段。
     * 这个简单实现按逗号分割，并去除字段两端的引号（如果存在）。
     * 注意：对于复杂的 CSV（例如字段内含逗号或引号），此方法可能需要增强或使用专业库。
     *
     * @param line 一行 CSV 文本
     * @return 字段列表
     */
    private static List<String> parseCsvLine(String line) {
        List<String> fields = new ArrayList<>();
        // 当前字段的起始索引
        int start = 0;
        boolean inQuoted = false; // 是否在引号范围内

        for (int i = 0; i < line.length(); i++) {
            char c = line.charAt(i);
            if (c == '"') {
                // 遇到引号，切换状态
                inQuoted = !inQuoted;
            } else if (c == ',' && !inQuoted) {
                // 遇到不在引号内的逗号，分割字段
                String field = line.substring(start, i).trim();
                // 去除字段两端的引号（如果有）
                if (field.startsWith("\"") && field.endsWith("\"") && field.length() > 1) {
                    field = field.substring(1, field.length() - 1);
                }
                fields.add(field);
                start = i + 1; // 更新下一个字段的起始位置
            }
        }
        // 添加最后一个字段
        String lastField = line.substring(start).trim();
        if (lastField.startsWith("\"") && lastField.endsWith("\"") && lastField.length() > 1) {
            lastField = lastField.substring(1, lastField.length() - 1);
        }
        fields.add(lastField);

        return fields;
    }

    /**
     * 使用示例：读取 CSV 文件并打印内容
     */
    public static void main(String[] args) {
        File csvFile = new File("data.csv"); // 替换为你的 CSV 文件路径

        try {
            List<Map<String, String>> csvData = readCsv(csvFile);
            // 打印读取到的 CSV 数据
            for (Map<String, String> row : csvData) {
                for (Map.Entry<String, String> entry : row.entrySet()) {
                    System.out.println(entry.getKey() + ": " + entry.getValue());
                }
                System.out.println("------"); // 行分隔符
            }
        } catch (IOException e) {
            System.err.println("读取 CSV 文件时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
}